package com.zhuang.sms.netty.handler;

import com.zhuang.sms.netty.config.GCmd;
import com.zhuang.sms.netty.config.RoomEntity;
import com.zhuang.sms.proto.ChatMessageOuterClass.ChatMessage;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.AttributeKey;
import io.netty.util.concurrent.GlobalEventExecutor;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@ChannelHandler.Sharable
public class WebSocketProtobufHandler extends ChannelInboundHandlerAdapter {

    private static final Map<String, Channel> channels = new ConcurrentHashMap<>();


    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        String ipPort = ctx.channel().remoteAddress().toString();
        String userId = generateUserId(ipPort); // 获取用户ID
        ctx.channel().attr(AttributeKey.valueOf(userId)).set(userId);
        channels.put(userId, ctx.channel());
        System.out.println("User " + userId + " connected!");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        String ipPort = ctx.channel().remoteAddress().toString();
        String userId = generateUserId(ipPort); // 获取用户ID
        channels.remove(userId);
        System.out.println("User " + userId + " disconnected!");
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof TextWebSocketFrame) {

            // 如果是文本帧，则按需处理
            TextWebSocketFrame frame = (TextWebSocketFrame) msg;
            String text = frame.text();
            TextWebSocketFrame textFrame = new TextWebSocketFrame(text);
            ctx.writeAndFlush(textFrame);
            System.out.println("Received a text message: " + text);
        } else if (msg instanceof BinaryWebSocketFrame) {
            // 假设之前已经配置了pipeline中的ProtobufDecoder来解码二进制数据到protobuf消息

            BinaryWebSocketFrame binaryWebSocketFrame = (BinaryWebSocketFrame)msg;
            ByteBuf content = binaryWebSocketFrame.content();

            // 将ByteBuf内容复制到一个新的字节数组
            byte[] bytes = new byte[content.readableBytes()];
            content.getBytes(content.readerIndex(), bytes);

            // 解码protobuf消息
            ChatMessage chatMessage = ChatMessage.parseFrom(bytes);

            // 处理接收到的Protobuf消息
            System.out.println("Received a protobuf message:");
            System.out.println("Sender: " + chatMessage.getSender());
            System.out.println("Message: " + chatMessage.getMessageText());
            System.out.println("Timestamp: " + chatMessage.getTimestamp());


            ChatMessage alice = ChatMessage.newBuilder()
                    .setSender("天神")
                    .setMessageText(chatMessage.getMessageText())
                    .setTimestamp(System.currentTimeMillis())/**这个时间分布式不知道怎么搞*/
                    .build();


            // 将 Alice 的消息编码为二进制数据
            byte[] aliceBytes = alice.toByteArray();

            // 创建一个 ByteBuf 来存储二进制数据
            ByteBuf encodedAliceMessage = ByteBufAllocator.DEFAULT.buffer(aliceBytes.length);
            encodedAliceMessage.writeBytes(aliceBytes);

            // 创建一个 BinaryWebSocketFrame 包含编码后的二进制数据

            // 在 ChannelHandlerContext 上发送 WebSocket 消息
            ctx.writeAndFlush(new BinaryWebSocketFrame(encodedAliceMessage));

//            sendMessageToClient(ctx, alice);


            // 示例：将接收到的消息转成TextWebSocketFrame转发给客户端
            // 注意实际应用中可能不需要直接转发，此处仅为演示
//            TextWebSocketFrame textFrame = new TextWebSocketFrame(chatMessage.toString());
//            ctx.writeAndFlush(textFrame);

        }
    }

    // ... 其他channelActive和channelInactive方法 ...


    // 假设我们从HTTP请求头或WebSocket连接时传递的参数中获取用户ID
    private String generateUserId(String ipPort) {
        // 在WebSocket握手阶段（例如：HTTP请求升级为WebSocket连接时），可以从HTTP请求的Header、Cookie或其他有效身份凭证中提取用户ID
        // 这是一个模拟实现，实际中应替换为你的认证和用户ID获取机制
        return "userId" + ipPort; // 临时返回一个固定值，实际应替换为实际用户ID
    }

    /**
     * 封装一个方法用于向客户端发送Protobuf消息
     */
    public void sendMessageToClient(ChannelHandlerContext ctx, ChatMessage message) {
        // 使用BinaryWebSocketFrame发送二进制数据
        ByteBuf encodedMessage = Unpooled.wrappedBuffer(message.toByteArray());
        ctx.writeAndFlush(new BinaryWebSocketFrame(encodedMessage));
    }


}